﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net;


namespace WindowsFormsApplication9
{
    public abstract class iDS
    {
        protected virtual string fileName { get; set; }
        public virtual void Clear() { throw new ArgumentNullException("IDataStorage: Not valid Data, try IDS_Classed"); }
        public virtual void Create(Person _newPerson) { throw new ArgumentNullException("IDataStorage: Not valid Data, try IDS_Classed"); }
        public virtual List<Person> Read() { throw new ArgumentNullException("IDataStorage: Not valid Data, try IDS_Classed"); }
        public virtual void Delete(int id) { throw new ArgumentNullException("IDataStorage: Not valid Data, try IDS_Classed"); }
        public virtual void Update(int id, Person _PersonDataToUpdate) { throw new ArgumentNullException("IDataStorage: Not valid Data, try IDS_Classed"); }
        public virtual iDS IsReady(string filename) { return null; }
        public virtual string GetFilter() { return ""; }
        public iDS next { get; set; }


    } //---- class iDS

    public class DS_Net_Client : iDS
    {
        Socket client;
        private List<Person> SendToServer(string request)
        {
            List<Person> list = new List<Person>();
            try
            {
                //send
                string host = System.Net.Dns.GetHostName();
                  IPAddress ipAddr = IPAddress.Parse("127.0.0.1");
                //IPAddress ipAddr = Dns.GetHostByName(host).AddressList[0];
                //IPAddress ipAddr = Dns.GetHostEntry("127.0.0.1").AddressList[0];
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 8060);

                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(ipEndPoint);
                Thread.Sleep(50);
                byte[] msg = Encoding.UTF8.GetBytes(request + "\n");
                client.Send(msg);
                
                
                NetworkStream stream = new NetworkStream(client);
                string answer = "";
                while (!stream.DataAvailable)
                {
                    Thread.Sleep(50);
                }
                while (stream.DataAvailable)
                {
                        int size1 = client.Available;
                        byte[] text = new byte[size1];
                        client.Receive(text);
                        answer += Encoding.UTF8.GetString(text);
                }
                MessageBox.Show(answer, "response from TcpServer");

                //close NetworkStream
                stream.Close();
                //analyse answer from Net_Server
                if (answer == "fail")
                {
                    throw new Exception("command failed");
                }

                // else
                // Parsing the answer
                if (answer != "success") // means READ()
                {
                    
                    string[] data = answer.Split('\n');
                    for (int i = 0; i < data.Length - 1; i++)
                    {
                        Person a = new Person();
                        a.CreateFromLineCsv(data[i]);
                        list.Add(a);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "EXCEPTION");
            }
            finally
            {
                client.Close();
            }
            return list;
        }
        //--------------------------------------------------------
        public override void Clear()
        {
            string request = "CLEAR;";
            SendToServer(request);
        }

        //--------------------------------------------------------
        public override void Create(Person _newPerson)
        {
            string request = "CREATE;" + _newPerson.ReturnLineToCsv();
            SendToServer(request);
        }

        //--------------------------------------------------------
        public override List<Person> Read()
        {
            string request = "READ;";
            return SendToServer(request);
        }

        //--------------------------------------------------------
        public override void Delete(int id)
        {
            string request = "DELETE;" + Convert.ToString(id);
            SendToServer(request);
        }

        //--------------------------------------------------------
        public override void Update(int id, Person _newPerson)
        {
            string request = "UPDATE;" + Convert.ToString(id) + ";" + _newPerson.ReturnLineToCsv();
            SendToServer(request);
        }

        //--------------------------------------------------------
        public override iDS IsReady(string namefile)
        {

            iDS temp = null;
            if (namefile == ".port")
            {
                this.fileName = namefile;
                temp = this;
            }
            else if (this.next != null)
            {
                temp = next.IsReady(this.fileName);
            }
            return temp;
        }

        //--------------------------------------------------------
        public override string GetFilter()
        {
            string temp = "TcpClient (*.port)|*.port";
            if (this.next != null)
            {
                temp += "|" + next.GetFilter();
            }
            return temp;
        }

        public void SendFile(string fileName)
        {
            TcpClient client = new TcpClient();
            try
            {
                byte[] file = File.ReadAllBytes(fileName);
                string[] name = fileName.Split('\\');
                string request = "SENDFILE;" + name[name.Length - 1] + ";";
                //send
                client.Connect("127.0.0.1", 8060);
                byte[] text = Encoding.UTF8.GetBytes(request);
                NetworkStream stream = client.GetStream();
                stream.Write(text, 0, text.Length);
                stream.Flush();
                stream.Flush();
                Thread.Sleep(20);
                stream.Write(file, 0, file.Length);
                stream.Flush();
                //recieve
                text = new byte[10*1024*1024];
                int size = stream.Read(text, 0, 10*1024 * 1024);
                string answer = Encoding.UTF8.GetString(text, 0, size);

                //close NetworkStream
                stream.Close();
                //analyse answer from Net_Server
                if (answer == "fail")
                {
                    throw new SystemException("command failed");
                }
                if (answer == "success")
                {
                    throw new SystemException("SUCCESS");
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "EXCEPTION");
            }
            finally
            {
                client.Close();
            }
            
        }
    }
}
